package com.skyolder.milkbee.web.rest.my;

import java.net.URI;
import java.net.URISyntaxException;
import java.time.ZonedDateTime;
import java.util.List;
import java.util.Optional;

import javax.inject.Inject;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.codahale.metrics.annotation.Timed;
import com.skyolder.milkbee.domain.Leaguer;
import com.skyolder.milkbee.domain.Ware;
import com.skyolder.milkbee.service.ExchangeRecordService;
import com.skyolder.milkbee.service.LeaguerService;
import com.skyolder.milkbee.service.WareService;
import com.skyolder.milkbee.service.dto.ExchangeRecordDTO;
import com.skyolder.milkbee.service.dto.ExchangeRecordDTO.ScheduleState;
import com.skyolder.milkbee.web.rest.util.HeaderUtil;
import com.skyolder.milkbee.web.rest.util.PaginationUtil;
import com.skyolder.milkbee.web.util.WebUserUtil;

import io.swagger.annotations.ApiParam;

/**
 * REST controller for managing ExchangeRecord.
 */
@RestController("myExchangeRecordResource")
@RequestMapping("/api/my")
public class ExchangeRecordResource {

	private final Logger log = LoggerFactory.getLogger(ExchangeRecordResource.class);

	@Inject
	private ExchangeRecordService exchangeRecordService;
	@Inject
	private WareService wareService;
	@Inject
	private WebUserUtil webUserUtil;
	@Inject
	private LeaguerService leaguerService;

	/**
	 * POST /exchange-records : Create a new exchangeRecord.
	 *
	 * @param exchangeRecordDTO
	 *            the exchangeRecordDTO to create
	 * @return the ResponseEntity with status 201 (Created) and with body the
	 *         new exchangeRecordDTO, or with status 400 (Bad Request) if the
	 *         exchangeRecord has already an ID
	 * @throws URISyntaxException
	 *             if the Location URI syntax is incorrect
	 */
	@PostMapping("/exchange-records")
	@Timed
	public ResponseEntity<ExchangeRecordDTO> createExchangeRecord(@RequestBody ExchangeRecordDTO exchangeRecordDTO)
			throws URISyntaxException {
		log.debug("REST request to save ExchangeRecord : {}", exchangeRecordDTO);
		if (exchangeRecordDTO.getId() != null) {
			return ResponseEntity.badRequest().headers(HeaderUtil.createFailureAlert("exchangeRecord", "idexists",
					"A new exchangeRecord cannot already have an ID")).body(null);
		}
		ExchangeRecordDTO result = exchangeRecordService.save(exchangeRecordDTO);
		return ResponseEntity.created(new URI("/api/exchange-records/" + result.getId()))
				.headers(HeaderUtil.createEntityCreationAlert("exchangeRecord", result.getId().toString()))
				.body(result);
	}

	@PostMapping("/exchange-records/ware/{id}")
	@Timed
	public ResponseEntity<ExchangeRecordDTO> createExchangeRecord(@PathVariable Long id) throws URISyntaxException {
		Ware ware = wareService.findOne(id);
		if (ware == null) {
			return new ResponseEntity<>(HttpStatus.NOT_FOUND);
		}
		int sur = ware.getSurplus();
		sur--;
		if (sur < 0) {
			return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
		}
		ware.setSurplus(sur);
		wareService.save(ware);
		Leaguer leaguer = webUserUtil.getCurrentLeaguer();
		long score = leaguer.getScore();
		score = score - ware.getScore();
		if (score < 0) {
			++sur;
			ware.setSurplus(sur);
			wareService.save(ware);
			return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
		}
		leaguer.setScore(score);
		leaguerService.save(leaguer);
		ExchangeRecordDTO exchangeRecordDTO = new ExchangeRecordDTO();
		exchangeRecordDTO.setCost(ware.getScore());
		exchangeRecordDTO.setCreatedAt(ZonedDateTime.now());
		exchangeRecordDTO.setHistory("");
		exchangeRecordDTO.setLeaguerId(webUserUtil.getCurrentLeaguer().getId());
		exchangeRecordDTO.setModifiedAt(ZonedDateTime.now());
		exchangeRecordDTO.setName(ware.getName());
		exchangeRecordDTO.setQuantum(1);
		exchangeRecordDTO.setSchedule("申请");
		exchangeRecordDTO.setUserId(webUserUtil.getCurrentUser().getId());
		exchangeRecordDTO.setWareId(ware.getId());
		ExchangeRecordDTO result = exchangeRecordService.save(exchangeRecordDTO);
		return ResponseEntity.created(new URI("/api/exchange-records/" + result.getId()))
				.headers(HeaderUtil.createEntityCreationAlert("exchangeRecord", result.getId().toString()))
				.body(result);
	}

	/**
	 * PUT /exchange-records : Updates an existing exchangeRecord.
	 *
	 * @param exchangeRecordDTO
	 *            the exchangeRecordDTO to update
	 * @return the ResponseEntity with status 200 (OK) and with body the updated
	 *         exchangeRecordDTO, or with status 400 (Bad Request) if the
	 *         exchangeRecordDTO is not valid, or with status 500 (Internal
	 *         Server Error) if the exchangeRecordDTO couldnt be updated
	 * @throws URISyntaxException
	 *             if the Location URI syntax is incorrect
	 */
	@PutMapping("/exchange-records")
	@Timed
	public ResponseEntity<ExchangeRecordDTO> updateExchangeRecord(@RequestBody ExchangeRecordDTO exchangeRecordDTO)
			throws URISyntaxException {
		log.debug("REST request to update ExchangeRecord : {}", exchangeRecordDTO);
		if (exchangeRecordDTO.getId() == null) {
			return createExchangeRecord(exchangeRecordDTO);
		}
		ExchangeRecordDTO result = exchangeRecordService.save(exchangeRecordDTO);
		return ResponseEntity.ok()
				.headers(HeaderUtil.createEntityUpdateAlert("exchangeRecord", exchangeRecordDTO.getId().toString()))
				.body(result);
	}

	/**
	 * GET /exchange-records : get all the exchangeRecords.
	 *
	 * @param pageable
	 *            the pagination information
	 * @return the ResponseEntity with status 200 (OK) and the list of
	 *         exchangeRecords in body
	 * @throws URISyntaxException
	 *             if there is an error to generate the pagination HTTP headers
	 */
	@GetMapping("/exchange-records")
	@Timed
	public ResponseEntity<List<ExchangeRecordDTO>> getAllExchangeRecords(@ApiParam Long stat,
			@ApiParam Pageable pageable) throws URISyntaxException {
		String schedule = "";
		if (stat == null) {
			stat = 1L;
		}
		switch (stat.intValue()) {
		case 1:
			schedule = ScheduleState.APPLY.getValue();
			break;
		case 2:
			schedule = ScheduleState.AGREE.getValue();
			break;
		case 3:
			schedule = ScheduleState.COMPLITE.getValue();
			break;
		case 4:
			schedule = ScheduleState.DENY.getValue();
			break;
		default:
			schedule = ScheduleState.APPLY.getValue();
		}
		Long userId = webUserUtil.getCurrentUser().getId();
		Page<ExchangeRecordDTO> page = exchangeRecordService.findByUserIdAndSchedule(userId, schedule, pageable);
		HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(page, "/api/exchange-records");
		return new ResponseEntity<>(page.getContent(), headers, HttpStatus.OK);
	}

	/**
	 * GET /exchange-records/:id : get the "id" exchangeRecord.
	 *
	 * @param id
	 *            the id of the exchangeRecordDTO to retrieve
	 * @return the ResponseEntity with status 200 (OK) and with body the
	 *         exchangeRecordDTO, or with status 404 (Not Found)
	 */
	@GetMapping("/exchange-records/{id}")
	@Timed
	public ResponseEntity<ExchangeRecordDTO> getExchangeRecord(@PathVariable Long id) {
		log.debug("REST request to get ExchangeRecord : {}", id);
		ExchangeRecordDTO exchangeRecordDTO = exchangeRecordService.findOne(id);
		return Optional.ofNullable(exchangeRecordDTO).map(result -> new ResponseEntity<>(result, HttpStatus.OK))
				.orElse(new ResponseEntity<>(HttpStatus.NOT_FOUND));
	}

	/**
	 * DELETE /exchange-records/:id : delete the "id" exchangeRecord.
	 *
	 * @param id
	 *            the id of the exchangeRecordDTO to delete
	 * @return the ResponseEntity with status 200 (OK)
	 */
	@DeleteMapping("/exchange-records/{id}")
	@Timed
	public ResponseEntity<Void> deleteExchangeRecord(@PathVariable Long id) {
		log.debug("REST request to delete ExchangeRecord : {}", id);
		exchangeRecordService.delete(id);
		return ResponseEntity.ok().headers(HeaderUtil.createEntityDeletionAlert("exchangeRecord", id.toString()))
				.build();
	}

}
